package com.battery.minapp.controller;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.battery.common.enums.*;
import com.battery.common.utils.BatteryJSONResult;
import com.battery.common.utils.Constants;
import com.battery.common.utils.DateUtils;
import com.battery.common.utils.ali.AliPayEntity;
import com.battery.common.utils.http.HttpClientJSONUtil;
import com.battery.common.utils.security.Md5Utils;
import com.battery.minapp.config.properties.AliPayResource;
import com.battery.system.domain.*;
import com.battery.system.service.battery.*;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.math.BigDecimal;
import java.util.Date;


/**
 * 设备请求处理接口
 */
@RestController
@RequestMapping("/wx/request")
public class RemoteRequestController {


    private static final Logger LOGGER = LoggerFactory.getLogger(RemoteRequestController.class);

    @Autowired
    private IUsedService usedService;

    @Autowired
    private IAuthUsedService authUsedService;

    @Autowired
    private AliPayResource aliPayResource;

    @Autowired
    private IDeviceBasicsService deviceBasicsService;


    @Autowired
    private IProrelyService prorelyService;

    @Autowired
    private IDeviceService deviceService;

    @Autowired
    private IOrderService orderService;

    private AliPayEntity _callApi() {
        AliPayEntity entity = new AliPayEntity();
        entity.setAppId(aliPayResource.getAppId());
        entity.setAlipayPublicKey(aliPayResource.getAlipayPublicKey());
        entity.setCharset(aliPayResource.getCharset());
        entity.setGatewayUrl(aliPayResource.getGatewayUrl());
        entity.setMerchantPrivateKey(aliPayResource.getMerchantPrivateKey());
        entity.setSignType(aliPayResource.getSignType());
        entity.setNotifyUrl(aliPayResource.getNotifyUrl());
        entity.setPayeeLogonId(aliPayResource.getPayeeLogonId());
        entity.setPayeeUserId(aliPayResource.getPayeeUserId());
        entity.setFreezeNotifyUrl(aliPayResource.getFreezeNotifyUrl());
        entity.setServiceId(aliPayResource.getServiceId());
        return entity;
    }


    /**
     * WS设备 心跳库存 完结订单
     *
     * @return
     */
    @PostMapping("/wsHeartbeatBattery")
    @ResponseBody
    public BatteryJSONResult wsHeartbeatBattery(@RequestBody JSONObject obj) {
        String device_id = obj.getString("device_id");
        String sign = obj.getString("sign");

        if (StringUtils.isBlank(device_id) || StringUtils.isBlank(sign)) {
            return BatteryJSONResult.errorMsg("存在必传参数为空");
        }


        String salt = Constants.ws_borrow_slat;
        String before = device_id + salt;
        if (!sign.equals(Md5Utils.hash(before))) {
            return BatteryJSONResult.errorMsg("签名错误");
        }
        DeviceBasics deviceBasics = deviceBasicsService.selectByPrimaryKey(device_id);
        if (deviceBasics == null) {
            return BatteryJSONResult.errorMsg("查找不到对应的设备信息");
        }
        String devStock = deviceBasics.getStock();
        if (StringUtils.isBlank(devStock)) {
            return BatteryJSONResult.errorMsg("查找不到对应的库存信息");
        }
        Date devUpdateStockTime = deviceBasics.getStockUpdateTime();
        Device device = deviceService.selectByPrimaryKey(device_id);

        LOGGER.info("[WS设备 心跳库存 完结订单]-->开始处理-->" + device.getSn());

        // 心跳结束订单的，需要将对应的归还机柜SN,归还卡槽位保存到租借记录中
        AliPayEntity entity = _callApi();
        Integer devAllBatteryCount = deviceBasics.getAllBattery();
        JSONObject json = JSON.parseObject(devStock);
        for (int i = 1; i <= devAllBatteryCount; i++) {
            JSONObject obj_ = JSON.parseObject(json.getString("S" + i));
            String batterySn = obj_.getString("batterySn");
            if (!"0".equals(batterySn)) {
                // 查询该电池是否存在正在借用中的订单
                obj_.put("deviceId", device_id); // 归还的设备ID
                obj_.put("backSn", device.getSn()); // 归还的机柜SN
                obj_.put("slot", i); // 归还的机柜SN
                Used used = usedService.selectOneInProgressByBatterySn(batterySn);
                if (used != null && used.getCreateTime().getTime() + 600 * 1000 < devUpdateStockTime.getTime()) {
                    usedService.wsDevRequestEndUsed(used, entity, obj_);
                }
            }
        }
        return BatteryJSONResult.ok();
    }


    /**
     * 定时任务处理微信支付分租借失败的订单，处于初始状态的订单
     *
     * @param obj
     * @return
     */
    @PostMapping("/taskToDoWxWarrantFailHandle")
    @ResponseBody
    public BatteryJSONResult taskToDoWxWarrantFailHandle(@RequestBody JSONObject obj) {
        String used_id = obj.getString("used_id");
        String sign = obj.getString("sign");
        if (StringUtils.isBlank(used_id) || StringUtils.isBlank(sign)) {
            return BatteryJSONResult.errorMsg("存在必传参数为空");
        }
        String before = used_id + ",";
        if (!sign.equals(Md5Utils.hash(before))) {
            return BatteryJSONResult.errorMsg("签名错误");
        }
        Used used = usedService.selectByPrimaryKey(used_id);
        if (used == null) {
            return BatteryJSONResult.errorMsg("查询不到对应的租借订单");
        }
        LOGGER.info("[定时任务处理微信支付分租借失败的订单，处于初始状态的订单]-->开始处理used_id-->" + used_id);
        return authUsedService.doWxRevokeOrder(used_id);
    }

    /**
     * 定时任务处理支付宝租借失败的订单，处于初始状态的订单
     *
     * @param obj
     * @return
     */
    @PostMapping("/taskToDoAliWarrantFailHandle")
    @ResponseBody
    public BatteryJSONResult taskToDoAliWarrantFailHandle(@RequestBody JSONObject obj) {
        String used_id = obj.getString("used_id");
        String sign = obj.getString("sign");
        if (StringUtils.isBlank(used_id) || StringUtils.isBlank(sign)) {
            return BatteryJSONResult.errorMsg("存在必传参数为空");
        }
        String before = used_id + ",";
        if (!sign.equals(Md5Utils.hash(before))) {
            return BatteryJSONResult.errorMsg("签名错误");
        }
        Used used = usedService.selectByPrimaryKey(used_id);
        if (used == null) {
            return BatteryJSONResult.errorMsg("查询不到对应的租借订单");
        }
        LOGGER.info("[定时任务处理支付宝租借失败的订单，处于初始状态的订单]-->开始处理used_id-->" + used_id);
        AliPayEntity entity = _callApi();
        return authUsedService.doUnfreeze(used_id, entity);
    }

    /**
     * 定时任务 结束99元订单
     *
     * @param obj
     * @return
     */
    @PostMapping("/taskEndDepositUsed")
    @ResponseBody
    public BatteryJSONResult taskEndDepositUsed(@RequestBody JSONObject obj) {
        String used_id = obj.getString("used_id");
        BigDecimal costPrice = obj.getBigDecimal("costPrice");
        Date backDate = obj.getDate("backDate");
        String sign = obj.getString("sign");
        if (StringUtils.isBlank(used_id) ||
                backDate == null ||
                costPrice == null
                || StringUtils.isBlank(sign)) {
            return BatteryJSONResult.errorMsg("存在必传参数为空");
        }
        String before = used_id + "," + costPrice + "," + DateUtils.parseDateToStr(DateUtils.YYYY_MM_DD_HH_MM_SS, backDate);
        if (!sign.equals(Md5Utils.hash(before))) {
            return BatteryJSONResult.errorMsg("签名错误");
        }
        Used used = usedService.selectByPrimaryKey(used_id);
        if (used == null) {
            return BatteryJSONResult.errorMsg("查询不到对应的租借订单");
        }
        AliPayEntity entity = _callApi();
        return usedService.taskEndDepositUsed(used, costPrice, backDate, entity);
    }

    /**
     * WS设备 归还消息 结束订单
     *
     * @param obj
     * @return
     */
    @PostMapping("/wsEndUsed")
    @ResponseBody
    public BatteryJSONResult wsEndUsed(@RequestBody JSONObject obj) {
        String used_id = obj.getString("used_id");
        String sn = obj.getString("sn");
        String batterySn = obj.getString("batterySn");
        String sign = obj.getString("sign");

        if (StringUtils.isBlank(used_id) || StringUtils.isBlank(sn) || StringUtils.isBlank(batterySn) || StringUtils.isBlank(sign)) {
            return BatteryJSONResult.errorMsg("存在必传参数为空");
        }

        String salt = Constants.ws_borrow_slat;
        String before = used_id + sn + batterySn + salt;
        if (!sign.equals(Md5Utils.hash(before))) {
            return BatteryJSONResult.errorMsg("签名错误");
        }

        Prorely prorely = prorelyService.selectBySn(sn);
        String service = prorely.getService();
        Integer port = prorely.getPort() + 100;
        try {
            // TODO 在完结订单之前发送归还确认消息, 异步执行
            String url = "http://" + service + ":" + port + "/dev/returnRS";
            JSONObject requestJSON = new JSONObject();
            requestJSON.put("sn", sn);
            requestJSON.put("batterySn", batterySn);
            String before_ = sn + batterySn + salt;
            requestJSON.put("sign", before_);
            HttpClientJSONUtil.postHttpJsonDataAsyn(url, requestJSON);
        } catch (IOException e) {
            e.printStackTrace();
        }

        Used used = usedService.selectByPrimaryKey(used_id);
        if (used == null) {
            return BatteryJSONResult.errorMsg("查询不到对应的租借订单");
        }
        if (YesOrNoEnum.YES.getCode().intValue() == used.getIsBack().intValue()) {
            return BatteryJSONResult.errorMsg("该笔租借订单已完结");
        }

        AliPayEntity entity = _callApi();
        return usedService.wsDevRequestEndUsed(used, entity, null);
    }


    /**
     * 租借失败，撤销订单
     *
     * @param obj
     * @return
     */
    @PostMapping("/revokeUsed")
    @ResponseBody
    public BatteryJSONResult revokeUsed(@RequestBody JSONObject obj) {
        String used_id = obj.getString("used_id");
        String sign = obj.getString("sign");

        if (StringUtils.isBlank(used_id) || StringUtils.isBlank(sign)) {
            return BatteryJSONResult.errorMsg("必填参数为空");
        }
        String salt = Constants.ws_borrow_slat;
        String before = used_id + salt;
        if (!Md5Utils.hash(before).equals(sign)) {
            return BatteryJSONResult.errorMsg("签名错误！");
        }
        Used used = usedService.selectByPrimaryKey(used_id);
        if (used == null) {
            return BatteryJSONResult.errorMsg("未查询到对应的租借订单");
        }
        if (BorrowModeEnum.FREE_DEPOSIT.type.intValue() != used.getBorrowMode().intValue()) {

            if (BorrowModeEnum.DEPOSIT.type.intValue() == used.getBorrowMode().intValue()) {

                // TODO 对押金订单进行解标记
                Order orderUpdate = new Order();
                orderUpdate.setId(used.getFalseOrderId());
                orderUpdate.setIsDepositSign(YesOrNoEnum.NO.getCode());
                orderService.updateByPrimaryKeySelective(orderUpdate);

            }
            return BatteryJSONResult.errorMsg("该笔订单不是授权订单");
        }
        if (LeaseStateEnum.SUCCESS.getCode() == used.getLeaseState()) {
            return BatteryJSONResult.errorMsg("该笔订单不可撤销");
        }

        AuthUsed authUsed = authUsedService.selectByPrimaryKey(used_id);
        if (UsedAuthStateEnum.REVOKED.type.equals(authUsed.getState())) {
            return BatteryJSONResult.errorMsg("该笔订单已撤销");
        }
        // 开始撤销订单
        if (UserTypeEnum.WX.getCode().intValue() == used.getChannel().intValue()) {
            // 微信免押
            authUsedService.doWxRevokeOrder(used_id);
        } else {
            // 支付宝
            AliPayEntity entity = _callApi();
            authUsedService.doUnfreeze(used_id, entity);
        }
        return BatteryJSONResult.ok();
    }

}
